/**
 * Copyright (c) 2015-2017, Henry Yang 杨勇 (gismail@foxmail.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.lambkit.module.cms;

import com.jfinal.config.Interceptors;
import com.jfinal.config.Routes;
import com.jfinal.kit.StrKit;
import com.jfinal.template.Engine;
import com.lambkit.Lambkit;
import com.lambkit.common.service.ServiceManager;
import com.lambkit.common.util.ScanJarStringSource;
import com.lambkit.core.rpc.RpcConfig;
import com.lambkit.db.datasource.ActiveRecordPluginWrapper;
import com.lambkit.module.LambkitModule;

import com.lambkit.module.cms.rpc.model.CmsArticle;
import com.lambkit.module.cms.rpc.model.CmsArticleCategory;
import com.lambkit.module.cms.rpc.model.CmsArticleTag;
import com.lambkit.module.cms.rpc.model.CmsCategory;
import com.lambkit.module.cms.rpc.model.CmsCategoryTag;
import com.lambkit.module.cms.rpc.model.CmsComment;
import com.lambkit.module.cms.rpc.model.CmsMenu;
import com.lambkit.module.cms.rpc.model.CmsPage;
import com.lambkit.module.cms.rpc.model.CmsSetting;
import com.lambkit.module.cms.rpc.model.CmsSystem;
import com.lambkit.module.cms.rpc.model.CmsTag;
import com.lambkit.module.cms.rpc.model.CmsTopic;
import com.lambkit.module.cms.rpc.api.CmsArticleService;
import com.lambkit.module.cms.common.CmsConfig;
import com.lambkit.module.cms.core.template.TemplateManager;
import com.lambkit.module.cms.rpc.api.CmsArticleCategoryService;
import com.lambkit.module.cms.rpc.api.CmsArticleTagService;
import com.lambkit.module.cms.rpc.api.CmsCategoryService;
import com.lambkit.module.cms.rpc.api.CmsCategoryTagService;
import com.lambkit.module.cms.rpc.api.CmsCommentService;
import com.lambkit.module.cms.rpc.api.CmsMenuService;
import com.lambkit.module.cms.rpc.api.CmsPageService;
import com.lambkit.module.cms.rpc.api.CmsSettingService;
import com.lambkit.module.cms.rpc.api.CmsSystemService;
import com.lambkit.module.cms.rpc.api.CmsTagService;
import com.lambkit.module.cms.rpc.api.CmsTopicService;
import com.lambkit.module.cms.rpc.service.impl.CmsArticleServiceImpl;
import com.lambkit.module.cms.rpc.service.impl.CmsArticleServiceMock;
import com.lambkit.module.cms.rpc.service.impl.CmsArticleCategoryServiceImpl;
import com.lambkit.module.cms.rpc.service.impl.CmsArticleCategoryServiceMock;
import com.lambkit.module.cms.rpc.service.impl.CmsArticleTagServiceImpl;
import com.lambkit.module.cms.rpc.service.impl.CmsArticleTagServiceMock;
import com.lambkit.module.cms.rpc.service.impl.CmsCategoryServiceImpl;
import com.lambkit.module.cms.rpc.service.impl.CmsCategoryServiceMock;
import com.lambkit.module.cms.rpc.service.impl.CmsCategoryTagServiceImpl;
import com.lambkit.module.cms.rpc.service.impl.CmsCategoryTagServiceMock;
import com.lambkit.module.cms.rpc.service.impl.CmsCommentServiceImpl;
import com.lambkit.module.cms.rpc.service.impl.CmsCommentServiceMock;
import com.lambkit.module.cms.rpc.service.impl.CmsMenuServiceImpl;
import com.lambkit.module.cms.rpc.service.impl.CmsMenuServiceMock;
import com.lambkit.module.cms.rpc.service.impl.CmsPageServiceImpl;
import com.lambkit.module.cms.rpc.service.impl.CmsPageServiceMock;
import com.lambkit.module.cms.rpc.service.impl.CmsSettingServiceImpl;
import com.lambkit.module.cms.rpc.service.impl.CmsSettingServiceMock;
import com.lambkit.module.cms.rpc.service.impl.CmsSystemServiceImpl;
import com.lambkit.module.cms.rpc.service.impl.CmsSystemServiceMock;
import com.lambkit.module.cms.rpc.service.impl.CmsTagServiceImpl;
import com.lambkit.module.cms.rpc.service.impl.CmsTagServiceMock;
import com.lambkit.module.cms.rpc.service.impl.CmsTopicServiceImpl;
import com.lambkit.module.cms.rpc.service.impl.CmsTopicServiceMock;
import com.lambkit.module.cms.web.interceptor.CmsWebInterceptor;
import com.lambkit.module.cms.web.tag.CmsArticleCategoryMarker;
import com.lambkit.module.cms.web.tag.CmsArticleMarker;
import com.lambkit.module.cms.web.tag.CmsArticleTagMarker;
import com.lambkit.module.cms.web.tag.CmsCategoryMarker;
import com.lambkit.module.cms.web.tag.CmsCategoryTagMarker;
import com.lambkit.module.cms.web.tag.CmsCommentMarker;
import com.lambkit.module.cms.web.tag.CmsMenuMarker;
import com.lambkit.module.cms.web.tag.CmsPageMarker;
import com.lambkit.module.cms.web.tag.CmsSettingMarker;
import com.lambkit.module.cms.web.tag.CmsSystemMarker;
import com.lambkit.module.cms.web.tag.CmsTagMarker;
import com.lambkit.module.cms.web.tag.CmsTopicMarker;
import com.lambkit.module.cms.web.directive.CmsArticleDirective;
import com.lambkit.module.cms.web.directive.CmsArticleCategoryDirective;
import com.lambkit.module.cms.web.directive.CmsArticleTagDirective;
import com.lambkit.module.cms.web.directive.CmsCategoryDirective;
import com.lambkit.module.cms.web.directive.CmsCategoryTagDirective;
import com.lambkit.module.cms.web.directive.CmsCommentDirective;
import com.lambkit.module.cms.web.directive.CmsMenuDirective;
import com.lambkit.module.cms.web.directive.CmsPageDirective;
import com.lambkit.module.cms.web.directive.CmsSettingDirective;
import com.lambkit.module.cms.web.directive.CmsSystemDirective;
import com.lambkit.module.cms.web.directive.CmsTagDirective;
import com.lambkit.module.cms.web.directive.CmsTopicDirective;

/**
 * @author yangyong 
 * @website: www.lambkit.com
 * @email: gismail@foxmail.com
 * @date 2019-10-22
 * @version 1.0
 * @since 1.0
 */
public class CmsModule extends LambkitModule  {

	@Override
	public void configMapping(ActiveRecordPluginWrapper arp) {
		if(StrKit.isBlank(getConfig().getDbconfig())) {
			mapping(arp);
		}
	}
	
	@Override
	public void configMapping(String name, ActiveRecordPluginWrapper arp) {
		super.configMapping(name, arp);
		if(StrKit.notBlank(name) && name.equals(getConfig().getDbconfig())) {
			mapping(arp);
		}
	}
	
	@Override
	public void configRoute(Routes me) {
		// TODO Auto-generated method stub
		me.add(new CmsAdminRoutes());
		me.add(new CmsWebRoutes());
	}
	
	@Override
	public void configEngine(Engine me) {
		// TODO Auto-generated method stub
		addDirective(me, "cmsArticle", CmsArticleDirective.class);
		addDirective(me, "cmsArticleCategory", CmsArticleCategoryDirective.class);
		addDirective(me, "cmsArticleTag", CmsArticleTagDirective.class);
		addDirective(me, "cmsCategory", CmsCategoryDirective.class);
		addDirective(me, "cmsCategoryTag", CmsCategoryTagDirective.class);
		addDirective(me, "cmsComment", CmsCommentDirective.class);
		addDirective(me, "cmsMenu", CmsMenuDirective.class);
		addDirective(me, "cmsPage", CmsPageDirective.class);
		addDirective(me, "cmsSetting", CmsSettingDirective.class);
		addDirective(me, "cmsSystem", CmsSystemDirective.class);
		addDirective(me, "cmsTag", CmsTagDirective.class);
		addDirective(me, "cmsTopic", CmsTopicDirective.class);
	}
	
	@Override
	public void configInterceptor(Interceptors me) {
	}

	@Override
	public void onStart() {
		// TODO Auto-generated method stub
		TemplateManager.me().init();
		addFreeMarker(this);
		if("server".equals(getConfig().getServerType())) {
			registerLocalService();
		} else if("client".equals(getConfig().getServerType())) {
			registerRemoteService();
		} 
	}
	
	public void mapping(ActiveRecordPluginWrapper arp) {
		arp.addSqlTemplate(new ScanJarStringSource("cms.sql"));
		
		arp.addMapping("cms_article", "article_id", CmsArticle.class);
		arp.addMapping("cms_article_category", "article_category_id", CmsArticleCategory.class);
		arp.addMapping("cms_article_tag", "article_tag_id", CmsArticleTag.class);
		arp.addMapping("cms_category", "category_id", CmsCategory.class);
		arp.addMapping("cms_category_tag", "category_tag_id", CmsCategoryTag.class);
		arp.addMapping("cms_comment", "comment_id", CmsComment.class);
		arp.addMapping("cms_menu", "menu_id", CmsMenu.class);
		arp.addMapping("cms_page", "page_id", CmsPage.class);
		arp.addMapping("cms_setting", "setting_id", CmsSetting.class);
		arp.addMapping("cms_system", "system_id", CmsSystem.class);
		arp.addMapping("cms_tag", "tag_id", CmsTag.class);
		arp.addMapping("cms_topic", "topic_id", CmsTopic.class);
	}
	
	public void addFreeMarker(LambkitModule lk) {
		lk.addTag("cmsArticle", new CmsArticleMarker());
		lk.addTag("cmsArticleCategory", new CmsArticleCategoryMarker());
		lk.addTag("cmsArticleTag", new CmsArticleTagMarker());
		lk.addTag("cmsCategory", new CmsCategoryMarker());
		lk.addTag("cmsCategoryTag", new CmsCategoryTagMarker());
		lk.addTag("cmsComment", new CmsCommentMarker());
		lk.addTag("cmsMenu", new CmsMenuMarker());
		lk.addTag("cmsPage", new CmsPageMarker());
		lk.addTag("cmsSetting", new CmsSettingMarker());
		lk.addTag("cmsSystem", new CmsSystemMarker());
		lk.addTag("cmsTag", new CmsTagMarker());
		lk.addTag("cmsTopic", new CmsTopicMarker());
	}
			
	public void registerLocalService() {
		registerLocalService(getRpcGroup(), getRpcVersion(), getRpcPort());
	}
	
	public void registerLocalService(String group, String version, int port) {
		ServiceManager.me().mapping(CmsArticleService.class, CmsArticleServiceImpl.class, CmsArticleServiceMock.class, group, version, port);
		ServiceManager.me().mapping(CmsArticleCategoryService.class, CmsArticleCategoryServiceImpl.class, CmsArticleCategoryServiceMock.class, group, version, port);
		ServiceManager.me().mapping(CmsArticleTagService.class, CmsArticleTagServiceImpl.class, CmsArticleTagServiceMock.class, group, version, port);
		ServiceManager.me().mapping(CmsCategoryService.class, CmsCategoryServiceImpl.class, CmsCategoryServiceMock.class, group, version, port);
		ServiceManager.me().mapping(CmsCategoryTagService.class, CmsCategoryTagServiceImpl.class, CmsCategoryTagServiceMock.class, group, version, port);
		ServiceManager.me().mapping(CmsCommentService.class, CmsCommentServiceImpl.class, CmsCommentServiceMock.class, group, version, port);
		ServiceManager.me().mapping(CmsMenuService.class, CmsMenuServiceImpl.class, CmsMenuServiceMock.class, group, version, port);
		ServiceManager.me().mapping(CmsPageService.class, CmsPageServiceImpl.class, CmsPageServiceMock.class, group, version, port);
		ServiceManager.me().mapping(CmsSettingService.class, CmsSettingServiceImpl.class, CmsSettingServiceMock.class, group, version, port);
		ServiceManager.me().mapping(CmsSystemService.class, CmsSystemServiceImpl.class, CmsSystemServiceMock.class, group, version, port);
		ServiceManager.me().mapping(CmsTagService.class, CmsTagServiceImpl.class, CmsTagServiceMock.class, group, version, port);
		ServiceManager.me().mapping(CmsTopicService.class, CmsTopicServiceImpl.class, CmsTopicServiceMock.class, group, version, port);
	}
	
	public void registerRemoteService() {
		registerRemoteService(getRpcGroup(), getRpcVersion(), getRpcPort());
	}
	
	public void registerRemoteService(String group, String version, int port) {
		ServiceManager.me().remote(CmsArticleService.class, CmsArticleServiceMock.class, group, version, port);
		ServiceManager.me().remote(CmsArticleCategoryService.class, CmsArticleCategoryServiceMock.class, group, version, port);
		ServiceManager.me().remote(CmsArticleTagService.class, CmsArticleTagServiceMock.class, group, version, port);
		ServiceManager.me().remote(CmsCategoryService.class, CmsCategoryServiceMock.class, group, version, port);
		ServiceManager.me().remote(CmsCategoryTagService.class, CmsCategoryTagServiceMock.class, group, version, port);
		ServiceManager.me().remote(CmsCommentService.class, CmsCommentServiceMock.class, group, version, port);
		ServiceManager.me().remote(CmsMenuService.class, CmsMenuServiceMock.class, group, version, port);
		ServiceManager.me().remote(CmsPageService.class, CmsPageServiceMock.class, group, version, port);
		ServiceManager.me().remote(CmsSettingService.class, CmsSettingServiceMock.class, group, version, port);
		ServiceManager.me().remote(CmsSystemService.class, CmsSystemServiceMock.class, group, version, port);
		ServiceManager.me().remote(CmsTagService.class, CmsTagServiceMock.class, group, version, port);
		ServiceManager.me().remote(CmsTopicService.class, CmsTopicServiceMock.class, group, version, port);
	}
	
	public int getRpcPort() {
		return Lambkit.config(RpcConfig.class).getDefaultPort();
	}
	
	public String getRpcGroup() {
		return Lambkit.config(RpcConfig.class).getDefaultGroup();
	}
	
	public String getRpcVersion() {
		return getConfig().getVersion();
	}
	
	public CmsConfig getConfig() {
		return Lambkit.config(CmsConfig.class);
	}
}

